package com.c6906.vdam.das.schedule;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.c6906.vdam.das.config.DasOpenStatus;
import com.c6906.vdam.das.dao.VehicleSetConfigDAO;
import com.c6906.vdam.das.model.entity.VehiclesSetConfig;
import com.c6906.vdam.das.common.OkHttpClientUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

@Component
@EnableConfigurationProperties({DasOpenStatus.class})
public class TerminalSet {

    private static final Logger logger = LoggerFactory.getLogger(TerminalSet.class);
    private static final int MAX_RETRY_TIMES = 1000;

    @Resource
    private VehicleSetConfigDAO vehicleSetConfigDAO;
    @Resource
    private DasOpenStatus openStatus;

    /**
     * 每五分钟定时执行终端参数设置任务, 并更新表记录
     */
    @Scheduled(cron = "0 0/5 * * * *")
    public void updateAndSetTerminalParam() {
        if (!isTaskExecutionEnabled()) {
            return;
        }

        List<String> ips = getIpList();
        List<VehiclesSetConfig> setConfigs = vehicleSetConfigDAO.selectAllTask();
        if (setConfigs.isEmpty()) {
            logger.info("【终端参数设置】没有设置终端参数任务");
            return;
        }

        logger.info("【终端参数设置】开始执行更新终端参数定时任务");
        setConfigs.forEach(settingTask -> processSettingTask(settingTask, ips));
    }

    // 判断任务是否可以执行
    private boolean isTaskExecutionEnabled() {
        return openStatus.isOpenStatus() && openStatus.isOpenLastGpsToRedis() && openStatus.getDcsIp() != null;
    }

    // 获取IP列表
    private List<String> getIpList() {
        return Arrays.asList(openStatus.getDcsIp().split(","));
    }

    // 处理每个设置任务
    private void processSettingTask(VehiclesSetConfig settingTask, List<String> ips) {
        int retryTimes = settingTask.getRetryTimes() + 1;
        JSONObject data = buildDataPayload(settingTask);

        int result = issuedTerminalParam(ips, data, settingTask);
        updateTaskStatus(result, retryTimes, settingTask);
    }

    // 构建任务的数据负载
    private JSONObject buildDataPayload(VehiclesSetConfig settingTask) {
        JSONObject data = new JSONObject();
        String clientId = settingTask.getTerminalSn().replaceAll("^0*", "");
        data.put("clientId", clientId);

        if (settingTask.getType() == 1) {
            JSONObject parameters = buildParameters(settingTask);
            data.put("total", parameters.size());
            data.put("parameters", parameters);
        } else if (settingTask.getType() == 2) {
            data.put("sign", 1);
            data.put("type", 1);
            data.put("content", settingTask.getText());
        }
        return data;
    }

    // 构建参数部分
    private JSONObject buildParameters(VehiclesSetConfig settingTask) {
        JSONObject parameters = new JSONObject();
        Optional.ofNullable(settingTask.getIp())
                .filter(ip -> !ip.isEmpty())
                .ifPresent(ip -> parameters.put("19", ip + ":" + settingTask.getPort()));
        Optional.ofNullable(settingTask.getHeartbeat()).ifPresent(value -> parameters.put("1", value));
        Optional.ofNullable(settingTask.getReportSleep()).ifPresent(value -> parameters.put("39", value));
        Optional.ofNullable(settingTask.getReportDefault()).ifPresent(value -> parameters.put("41", value));
        Optional.ofNullable(settingTask.getTurnTh()).ifPresent(value -> parameters.put("48", value));
        Optional.ofNullable(settingTask.getMiles()).ifPresent(value -> parameters.put("128", value));
        return parameters;
    }

    // 下发设置终端参数命令，并且更新标识 0失败 1成功
    private int issuedTerminalParam(List<String> ips, JSONObject data, VehiclesSetConfig settingTask) {
        for (String ip : ips) {
            String url;
            if (settingTask.getType() == 1) {
                url = String.format("http://%s:10004/device/8103", ip);
            } else {
                url = String.format("http://%s:10004/device/8300", ip);
            }
            try {
                String response = OkHttpClientUtil.doPostJson(url, data.toJSONString());
                JSONObject jsonObject = JSON.parseObject(response);
                if (isSuccessfulResponse(jsonObject)) {
                    logger.info("下发终端参数命令成功!{}", jsonObject);
                    return 1;
                }
            } catch (Exception e) {
                logger.error("设置终端参数失败, IP: {}!", ip, e);
            }
        }
        return 0;
    }

    // 判断是否响应成功
    private boolean isSuccessfulResponse(JSONObject jsonObject) {
        return jsonObject != null && ("200".equals(jsonObject.getString("code")) || "4002".equals(jsonObject.getString("code")));
    }

    // 更新任务状态
    private void updateTaskStatus(int result, int retryTimes, VehiclesSetConfig settingTask) {
        if (result == 1) {
            vehicleSetConfigDAO.updateSucessByCmdID(retryTimes, settingTask.getCmdId());
        } else if (retryTimes < MAX_RETRY_TIMES) {
            vehicleSetConfigDAO.updateRetryTimesByCmdID(retryTimes, settingTask.getCmdId(), DateUtil.date());
        } else {
            vehicleSetConfigDAO.updateTaskStatusByCmdID(retryTimes, settingTask.getCmdId(), DateUtil.date());
        }
    }
}